<template>
  <div class="panel-tab__content">
    <el-form :model="flowConditionForm" label-width="90px" size="small">
      <el-form-item label="流转类型">
        <el-select v-model="flowConditionForm.type" @change="updateFlowType">
          <el-option label="普通流转路径" value="normal" />
          <el-option label="默认流转路径" value="default" />
          <el-option label="条件流转路径" value="condition" />
        </el-select>
      </el-form-item>
      <el-form-item label="条件格式" v-if="flowConditionForm.type === 'condition'" key="condition">
        <el-select v-model="flowConditionForm.conditionType" @change="updateFlowCondition('')">
          <el-option label="flowable表达式" value="expression" />
          <el-option label="Spel表达式" value="Spel" />
<!--  yinjt 暂时没有好的设计方式         -->
<!--          <el-option label="表单数据" value="FormRuls" />-->
        </el-select>
      </el-form-item>
      <el-form-item
        label="表达式"
        v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'expression'"
        key="express"
      >
        <CodeMirrorEditor
            v-if="showCodeMirrorEditor"
            :mirrorWidth="`${props.width-160}px`"
            :mirrorHeight="`${50}px`"
            placeholder="请输入表达式"
            :codeStr="flowConditionForm.body"
            :handleChange="updateFlowCondition"
        />
      </el-form-item>
      <template
        v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'Spel'"
      >
        <el-form-item
          label="Spel表达式"
          key="body"
        >
        <CodeMirrorEditor
            v-if="showCodeMirrorEditor"
            :mirrorWidth="`${props.width-160}px`"
            :mirrorHeight="`${200}px`"
            placeholder="请输入脚本"
            :codeStr="flowConditionForm.body"
            :handleChange="updateFlowCondition"
        />
        </el-form-item>
      </template>
      <template
        v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'FormRuls'"
      >
        <el-form-item
          label="表单规则"
          key="body"
        >
          <CodeMirrorEditor
            v-if="showCodeMirrorEditor"
            :mirrorWidth="`${props.width-160}px`"
            :mirrorHeight="`${200}px`"
            placeholder="请输入脚本"
            :codeStr="flowConditionForm.body"
            :handleChange="updateFlowCondition"
          />
        </el-form-item>
      </template>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import {toRaw} from "vue";
import {createFormRuleGateWayConfigObject} from './utilSelf'


defineOptions({ name: 'FlowCondition' })

const props = defineProps({
  businessObject: Object,
  type: String ,
  width: Number
})
const prefix = inject('prefix')
const bpmnElementId = ref()
const flowConditionForm = ref<any>({})
const bpmnElement = ref()
const bpmnElementSource = ref()
const bpmnElementSourceRef = ref()
const flowConditionRef = ref()
const showCodeMirrorEditor = ref(true)
const bpmnInstances = () => (window as any)?.bpmnInstances
const resetFlowCondition = () => {
  bpmnElement.value = bpmnInstances().bpmnElement
  if(bpmnElementId.value != bpmnElement.value.id){
    showCodeMirrorEditor.value = false ;
    bpmnElementId.value = bpmnElement.value.id
  }
  bpmnElementSource.value = bpmnElement.value.source
  bpmnElementSourceRef.value = bpmnElement.value.businessObject.sourceRef
  // 初始化默认type为default
  flowConditionForm.value = { type: 'default' }
  if (
    bpmnElementSourceRef.value &&
    bpmnElementSourceRef.value.default &&
    bpmnElementSourceRef.value.default.id === bpmnElement.value.id
  ) {
    flowConditionForm.value = { type: 'default' }
  } else if (!bpmnElement.value.businessObject.conditionExpression) {
    // 普通
    flowConditionForm.value = { type: 'normal' }
  } else {
    // 带条件
    const conditionExpression = bpmnElement.value.businessObject.conditionExpression
    flowConditionForm.value = { ...conditionExpression, type: 'condition' }
    nextTick(()=>{
      showCodeMirrorEditor.value = true ;
      if(flowConditionForm.value.conditionType == "expression"){
      }else if(flowConditionForm.value.conditionType == "Spel"){
        let bodyStr = flowConditionForm.value.body
        flowConditionForm.value['body'] = getSpelCalculateStr(bodyStr) ;
      }else if(flowConditionForm.value.conditionType == "FormRuls"){
        let bodyStr = flowConditionForm.value.body
        console.log('FormRuls...flowConditionForm',flowConditionForm.value)
        flowConditionForm.value['body'] = bodyStr ;

        let formRuleGateWayConfigBpms =
          bpmnElement.value.businessObject?.extensionElements?.values?.filter(
            (ex) => ex.$type === `${prefix}:FormRuleGateWayConfig`
          ) ?? []
        let formRuleGateWayConfigList = formRuleGateWayConfigBpms.map((formRuleGateWayConfigBpm) =>
          JSON.parse(JSON.stringify(formRuleGateWayConfigBpm))
        )
        console.log('FormRuls...formRuleGateWayConfigList',formRuleGateWayConfigList)
      }
    })
  }
}
const updateFlowType = (flowType) => {
  // 正常条件类
  if (flowType === 'condition') {
    flowConditionRef.value = bpmnInstances().moddle.create('bpmn:FormalExpression')
    bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
      conditionExpression: flowConditionRef.value
    })
    return
  }
  // 默认路径
  if (flowType === 'default') {
    bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
      conditionExpression: null
    })
    bpmnInstances().modeling.updateProperties(toRaw(bpmnElementSource.value), {
      default: toRaw(bpmnElement.value)
    })
    return
  }
  // 正常路径，如果来源节点的默认路径是当前连线时，清除父元素的默认路径配置
  if (
    bpmnElementSourceRef.value.default &&
    bpmnElementSourceRef.value.default.id === bpmnElement.value.id
  ) {
    bpmnInstances().modeling.updateProperties(toRaw(bpmnElementSource.value), {
      default: null
    })
  }
  bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
    conditionExpression: null
  })
}
const updateFlowCondition = (codeStr) => {
  let { conditionType} = flowConditionForm.value
  let body = codeStr ;
  let condition
  flowConditionForm.value['body'] = ''
  let bpmnElementValue = {};

  // flowable 规则脚本
  if (conditionType === 'expression') {
    condition = bpmnInstances().moddle.create('bpmn:FormalExpression', {
      conditionType,
      body
    })
    bpmnElementValue.conditionExpression = condition

  }
  // Spel表达式
  else if (conditionType === 'Spel') {
    body = setSpelCalculateStr(codeStr)
      condition = bpmnInstances().moddle.create('bpmn:FormalExpression', {
        conditionType,
        body
      })

    bpmnElementValue.conditionExpression = condition
  }
  // 根据表单值控制
  else if (conditionType === 'FormRuls') {

    let formRuleGateWayConfig = {};
    formRuleGateWayConfig.event = "event123event"
    formRuleGateWayConfig.fields = [{ name:"nam1", stringValue:"stringValue1" }]

    let formRuleGateWayConfigObj = createFormRuleGateWayConfigObject(formRuleGateWayConfig,prefix);

    let formRuleGateWayConfigBpmn = bpmnInstances().moddle.create(
      `${prefix}:FormRuleGateWayConfig`,
      formRuleGateWayConfigObj
    );

    const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
      values: [formRuleGateWayConfigBpmn,formRuleGateWayConfigBpmn]
    })
    condition = bpmnInstances().moddle.create('bpmn:FormalExpression', {
      conditionType,
      body:body
    })

    bpmnElementValue.extensionElements = extensions ;
    bpmnElementValue.conditionExpression = condition ;
    }
  // 更新xml
  bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), bpmnElementValue)

}

const regex = /calculate\(.*?,\s*'([^']*)'\)/;

const getSpelCalculateStr = (originalStr)=>{
  const match = originalStr.match(regex);

  if (match && match[1]) {
    console.log("第二个参数:", match[1]); // 输出: **
    return unescapeSpelCalculateStr(match[1])
  }
  return "";
}
const setSpelCalculateStr = (spelCalculateStr)=>{

  let templateSpelCalculateStr = "${bpmBranchRuleSpelCalculate.calculate(execution,'**')}";
  spelCalculateStr = escapeSpelCalculateStr(spelCalculateStr)
// 替换内容
  templateSpelCalculateStr = templateSpelCalculateStr.replace(regex, (match, p1) => {
    return `calculate(execution, '${spelCalculateStr}')`;
  })
  return templateSpelCalculateStr ;
}

function escapeSpelCalculateStr(str) {
  return str
      .replace(/'/g, '&apos;')
      .replace(/"/g, '&quot;');
}

function unescapeSpelCalculateStr(str) {
  return str
      .replace(/&apos;/g, '\'')
      .replace(/&quot;/g, '"');
}

// 创建 监听器的注入字段 实例
function createMagicApiConfigFieldObject(option, prefix) {
  const { name, stringValue } = option
  const fieldConfig =  { name, stringValue }
  return bpmnInstances().moddle.create(`${prefix}:Field`, fieldConfig)
}

onBeforeUnmount(() => {
  bpmnElement.value = null
  bpmnElementSource.value = null
  bpmnElementSourceRef.value = null
  bpmnElementId.value = null
})

watch(
  () => props.businessObject,
  (val) => {
    console.log(val, 'val')
    nextTick(() => {
      resetFlowCondition()
    })
  },
  {
    immediate: true
  }
)
</script>
